"""
工作流控制器模块，负责管理六步测算流程
"""
from typing import Dict, List, Any, Optional
import logging

from models.scene import Scene
from core.scene_manager import SceneManager

logger = logging.getLogger(__name__)


class WorkflowController:
    """
    工作流控制器，负责管理六步测算流程
    """
    
    def __init__(self, scene_manager: SceneManager):
        """
        初始化工作流控制器
        
        Args:
            scene_manager: 场景管理器
        """
        self.scene_manager = scene_manager
        
        # 定义工作流步骤
        self.workflow_steps = [
            {
                "id": "scene_management",
                "name": "场景创建",
                "description": "创建和管理测算场景",
                "required": True
            },
            {
                "id": "parameter_setup",
                "name": "假设条件设置",
                "description": "设置测算参数和假设条件",
                "required": True
            },
            {
                "id": "data_import",
                "name": "数据导入",
                "description": "导入测算所需数据",
                "required": True
            },
            {
                "id": "data_preparation",
                "name": "数据准备",
                "description": "清洗和准备数据",
                "required": False
            },
            {
                "id": "calculation",
                "name": "执行测算",
                "description": "执行测算逻辑",
                "required": True
            },
            {
                "id": "results",
                "name": "结果查看",
                "description": "查看和分析测算结果",
                "required": False
            }
        ]
    
    def get_current_step(self, scene: Scene) -> Dict[str, Any]:
        """
        获取场景当前步骤
        
        Args:
            scene: 场景对象
            
        Returns:
            当前步骤信息
        """
        current_step_index = scene.current_step
        if 0 <= current_step_index < len(self.workflow_steps):
            return self.workflow_steps[current_step_index]
        else:
            # 默认返回第一步
            return self.workflow_steps[0]
    
    def get_next_step(self, scene: Scene) -> Optional[Dict[str, Any]]:
        """
        获取场景下一步骤
        
        Args:
            scene: 场景对象
            
        Returns:
            下一步骤信息，如果已是最后一步则返回None
        """
        current_step_index = scene.current_step
        next_step_index = current_step_index + 1
        
        if next_step_index < len(self.workflow_steps):
            return self.workflow_steps[next_step_index]
        else:
            return None
    
    def get_previous_step(self, scene: Scene) -> Optional[Dict[str, Any]]:
        """
        获取场景上一步骤
        
        Args:
            scene: 场景对象
            
        Returns:
            上一步骤信息，如果已是第一步则返回None
        """
        current_step_index = scene.current_step
        prev_step_index = current_step_index - 1
        
        if prev_step_index >= 0:
            return self.workflow_steps[prev_step_index]
        else:
            return None
    
    def move_to_next_step(self, scene_id: str) -> Optional[Scene]:
        """
        将场景移动到下一步骤
        
        Args:
            scene_id: 场景ID
            
        Returns:
            更新后的场景对象，如果场景不存在则返回None
        """
        scene = self.scene_manager.get_scene(scene_id)
        if not scene:
            return None
        
        current_step_index = scene.current_step
        next_step_index = current_step_index + 1
        
        if next_step_index < len(self.workflow_steps):
            # 更新场景状态
            scene = self.scene_manager.update_scene_status(
                scene_id, 
                "in_progress", 
                next_step_index
            )
            
            logger.info(f"场景 {scene_id} 移动到下一步: {self.workflow_steps[next_step_index]['name']}")
            return scene
        else:
            # 已是最后一步，标记为完成
            scene = self.scene_manager.update_scene_status(
                scene_id, 
                "completed", 
                current_step_index
            )
            
            logger.info(f"场景 {scene_id} 已完成所有步骤")
            return scene
    
    def move_to_previous_step(self, scene_id: str) -> Optional[Scene]:
        """
        将场景移动到上一步骤
        
        Args:
            scene_id: 场景ID
            
        Returns:
            更新后的场景对象，如果场景不存在则返回None
        """
        scene = self.scene_manager.get_scene(scene_id)
        if not scene:
            return None
        
        current_step_index = scene.current_step
        prev_step_index = current_step_index - 1
        
        if prev_step_index >= 0:
            # 更新场景状态
            scene = self.scene_manager.update_scene_status(
                scene_id, 
                "in_progress", 
                prev_step_index
            )
            
            logger.info(f"场景 {scene_id} 移动到上一步: {self.workflow_steps[prev_step_index]['name']}")
            return scene
        else:
            # 已是第一步，保持不变
            logger.info(f"场景 {scene_id} 已是第一步，无法后退")
            return scene
    
    def jump_to_step(self, scene_id: str, step_index: int) -> Optional[Scene]:
        """
        将场景跳转到指定步骤
        
        Args:
            scene_id: 场景ID
            step_index: 目标步骤索引
            
        Returns:
            更新后的场景对象，如果场景不存在则返回None
        """
        scene = self.scene_manager.get_scene(scene_id)
        if not scene:
            return None
        
        if 0 <= step_index < len(self.workflow_steps):
            # 更新场景状态
            scene = self.scene_manager.update_scene_status(
                scene_id, 
                "in_progress", 
                step_index
            )
            
            logger.info(f"场景 {scene_id} 跳转到步骤: {self.workflow_steps[step_index]['name']}")
            return scene
        else:
            logger.warning(f"无效的步骤索引: {step_index}")
            return scene
    
    def validate_step_completion(self, scene: Scene, step_index: Optional[int] = None) -> Dict[str, Any]:
        """
        验证指定步骤是否已完成
        
        Args:
            scene: 场景对象
            step_index: 步骤索引，默认为当前步骤
            
        Returns:
            验证结果，包含是否完成和错误信息
        """
        if step_index is None:
            step_index = scene.current_step
        
        if not (0 <= step_index < len(self.workflow_steps)):
            return {
                "completed": False,
                "errors": ["无效的步骤索引"]
            }
        
        step = self.workflow_steps[step_index]
        errors = []
        
        # 根据步骤ID验证完成情况
        if step["id"] == "scene_management":
            # 场景创建步骤，检查基本信息是否完整
            if not scene.name:
                errors.append("场景名称不能为空")
            if not scene.scene_type:
                errors.append("请选择场景类型")
        
        elif step["id"] == "parameter_setup":
            # 参数设置步骤，检查必要参数是否已设置
            if not scene.parameters:
                errors.append("请设置测算参数")
        
        elif step["id"] == "data_import":
            # 数据导入步骤，检查是否有数据源
            if not scene.data_sources:
                errors.append("请导入至少一个数据源")
        
        elif step["id"] == "calculation":
            # 执行测算步骤，检查是否有计算结果
            if not scene.calculation_results:
                errors.append("请执行测算")
        
        # 返回验证结果
        return {
            "completed": len(errors) == 0,
            "errors": errors
        }
    
    def get_workflow_progress(self, scene: Scene) -> Dict[str, Any]:
        """
        获取工作流进度信息
        
        Args:
            scene: 场景对象
            
        Returns:
            进度信息，包含总步骤数、当前步骤、已完成步骤等
        """
        total_steps = len(self.workflow_steps)
        current_step = scene.current_step
        
        # 计算已完成的步骤数
        completed_steps = 0
        for i in range(current_step):
            validation = self.validate_step_completion(scene, i)
            if validation["completed"]:
                completed_steps += 1
        
        # 计算进度百分比
        progress_percentage = (completed_steps / total_steps) * 100 if total_steps > 0 else 0
        
        return {
            "total_steps": total_steps,
            "current_step": current_step,
            "current_step_name": self.workflow_steps[current_step]["name"] if 0 <= current_step < total_steps else "",
            "completed_steps": completed_steps,
            "progress_percentage": progress_percentage,
            "status": scene.status
        }